﻿using System;
using System.Data;
using Npgsql;
using NpgsqlTypes;
using System.IO;
using System.ComponentModel;
using System.Web;
using System.Configuration;

namespace IonosphereViewer
{
    public partial class Dbwriter 
    {
        bool endian = BitConverter.IsLittleEndian;
        // исходный массив
        //заголовок
        ushort[] head = new ushort[10];
        byte[] b = new byte[223060];
        // переменные для заголовка
        DateTime mDateTime;
        // мощность сигнала
        uint[] m680 = new uint[680];
        uint[,] akf = new uint[170, 18];
        uint[] adc = new uint[680];
        ushort[] serv = new ushort[180];
        // v format
        uint[,] dat1 = new uint[230, 10];
        uint[,] dat2 = new uint[230, 10];
        uint[] apower = new uint[230];
        uint[] nadc1 = new uint[230];
        uint[] nadc2 = new uint[230];
        uint[] vserv = new uint[230];

        // s new format
        uint[,] akf1 = new uint[680, 19];
        uint[,] akf2 = new uint[680, 19];
        uint[,] akf3 = new uint[680, 19];
        uint[,] akf4 = new uint[680, 19];
        uint[] ipower1 = new uint[680];
        uint[] ipower2 = new uint[680];
        uint[] nsadc1 = new uint[680];
        uint[] nsadc2 = new uint[680];
        uint[] nsadc3 = new uint[680];
        uint[] nsadc4 = new uint[680];
        DataSet myDS = new DataSet();
        DataTable dt,dp,dta1,dta2,dd1,dd2;
        NpgsqlConnection conn;
        NpgsqlCommand command_v_power, command_v_adc1, command_v_adc2, command_v_dat1,command_v_dat2, commandh;
        string  command_h = "SELECT measure_date, seans, nr1, nr2 FROM headerall WHERE measure_type = :p_type AND id = :p_id";
        string  sql_v_power = "SELECT nadc as power FROM nulladc WHERE header_id = :p_hid AND canal = 0 AND dtype = 1";
        string  sql_v_adc1 = "SELECT nadc as adc1 FROM nulladc WHERE header_id = :p_hid AND canal =1 AND dtype = 0";
        string  sql_v_adc2 = "SELECT nadc as adc2 FROM nulladc WHERE header_id = :p_hid AND canal =2 AND dtype = 0";
        string  sql_v_dat1 = "SELECT string_to_array(array_to_string(akf,','),',')::bigint[] as dat1 FROM data_v WHERE header_id = :p_hid AND data_type = 1";
        string  sql_v_dat2 = "SELECT string_to_array(array_to_string(akf,','),',')::bigint[] as dat2 FROM data_v WHERE header_id = :p_hid AND data_type = 2";

        // s new format
        DataTable dts, dps,dtas,dtakf;
        NpgsqlCommand command_s_power, command_s_akf, command_s_adc;

        string sql_s_power = "SELECT nadc as power FROM nulladc WHERE header_id = :p_hid AND canal = 0 AND dtype = 1";
        string sql_s_adc   = "SELECT nadc as adc1 FROM nulladc WHERE header_id = :p_hid AND canal =0 AND dtype = 0";
        string sql_s_akf = "SELECT string_to_array(array_to_string(h_akf,','),',')::bigint[] as akf FROM datas WHERE header_id = :p_hid AND canal = 0";

        //--------------------------------------------------------------------------
        public string ExportVFile(int id, HttpContext context)
        {
            try
            {
                conn = new NpgsqlConnection(
                    String.Format("Server={0};Port={1};User Id={2};Password={3};Database={4};",
                       ConfigurationManager.AppSettings["host"],
                       ConfigurationManager.AppSettings["port"],
                       ConfigurationManager.AppSettings["user"],
                       ConfigurationManager.AppSettings["ps"],
                       ConfigurationManager.AppSettings["db"]));

                conn.Open();
                //--header---
                commandh = new NpgsqlCommand(command_h, conn);
                commandh.Parameters.Add(new NpgsqlParameter("p_type", NpgsqlDbType.Integer));
                commandh.Parameters.Add(new NpgsqlParameter("p_id", NpgsqlDbType.Bigint));
                commandh.Parameters["p_type"].Value = 2; //v тип
                commandh.Parameters["p_id"].Value = id;
                //--power---
                command_v_power = new NpgsqlCommand(sql_v_power, conn);
                command_v_power.Parameters.Add(new NpgsqlParameter("p_hid ", NpgsqlDbType.Bigint));
                command_v_power.Parameters["p_hid"].Value = id;
                //--adc1---
                command_v_adc1 = new NpgsqlCommand(sql_v_adc1, conn);
                command_v_adc1.Parameters.Add(new NpgsqlParameter("p_hid ", NpgsqlDbType.Bigint));
                command_v_adc1.Parameters["p_hid"].Value = id;
                //--adc2---
                command_v_adc2 = new NpgsqlCommand(sql_v_adc2, conn);
                command_v_adc2.Parameters.Add(new NpgsqlParameter("p_hid ", NpgsqlDbType.Bigint));
                command_v_adc2.Parameters["p_hid"].Value = id;
                //--dat1---
                command_v_dat1 = new NpgsqlCommand(sql_v_dat1, conn);
                command_v_dat1.Parameters.Add(new NpgsqlParameter("p_hid ", NpgsqlDbType.Bigint));
                command_v_dat1.Parameters["p_hid"].Value = id;
                //--dat2---
                command_v_dat2 = new NpgsqlCommand(sql_v_dat2, conn);
                command_v_dat2.Parameters.Add(new NpgsqlParameter("p_hid ", NpgsqlDbType.Bigint));
                command_v_dat2.Parameters["p_hid"].Value = id;
                try
                {
                    NpgsqlDataAdapter da = new NpgsqlDataAdapter(commandh);
                    NpgsqlDataAdapter da_p = new NpgsqlDataAdapter(command_v_power);
                    NpgsqlDataAdapter da_adc1 = new NpgsqlDataAdapter(command_v_adc1);
                    NpgsqlDataAdapter da_adc2 = new NpgsqlDataAdapter(command_v_adc2);
                    NpgsqlDataAdapter da_dat1 = new NpgsqlDataAdapter(command_v_dat1);
                    NpgsqlDataAdapter da_dat2 = new NpgsqlDataAdapter(command_v_dat2);
                    da.Fill(myDS, "header");
                    da_p.Fill(myDS, "power");
                    da_adc1.Fill(myDS, "adc1");
                    da_adc2.Fill(myDS, "adc2");
                    da_dat1.Fill(myDS, "dat1");
                    da_dat2.Fill(myDS, "dat2");
                    dt = myDS.Tables["header"];
                    dp = myDS.Tables["power"];
                    dta1 = myDS.Tables["adc1"];
                    dta2 = myDS.Tables["adc2"];
                    dd1 = myDS.Tables["dat1"];
                    dd2 = myDS.Tables["dat2"];
                    foreach (DataRow row in dd1.Rows)
                    {
                        long[] ts = (long[])row[0];
                        //foreach (long item in ts)
                        //{
                        //    // MessageBox.Show(item.ToString());
                        //}
                    }
                }
                catch (NpgsqlException nex)
                {
                    return nex.Message;
                }
                finally
                {
                    conn.Close();
                    conn.Dispose();
                    conn = null;
                }

                mDateTime = (DateTime)dt.Rows[0]["measure_date"];
                head[0] = (ushort)mDateTime.Day;
                head[1] = (ushort)mDateTime.Month;
                head[2] = (ushort)mDateTime.Year;
                head[3] = (ushort)mDateTime.Hour;
                head[4] = (ushort)mDateTime.Minute;
                head[5] = (ushort)mDateTime.Second;
                head[6] = ushort.Parse(dt.Rows[0]["seans"].ToString());
                head[7] = ushort.Parse(dt.Rows[0]["nr1"].ToString());
                head[8] = ushort.Parse(dt.Rows[0]["nr2"].ToString());

                String.Format("{0:00000}", 15);

                string attachment = String.Format("attachment; filename=V{0:00}{1:00}{2}.{3:000}", head[0], head[1], head[2].ToString().Substring(head[2].ToString().Length - 2, 2), head[6]);

                context.Response.ClearHeaders();
                context.Response.AddHeader("content-disposition", attachment);
                //context.Response.ContentType = "text/plain";  

                // Stream = new Stream("vfile222.dat", FileMode.Create);
                context.Response.Buffer = false;
                context.Response.ContentType = "application/octet-stream";

                int len = 22460;
                context.Response.AppendHeader("content-length", len.ToString());
                byte[] buffer = new byte[1024];
                Stream outStream = context.Response.OutputStream;

                // write header
                foreach (ushort i in head)
                {
                    byte[] bytes2 = System.BitConverter.GetBytes(i);
                    if (endian) Array.Reverse(bytes2, 0, 2);
                    outStream.Write(bytes2, 0, 2);

                }

                for (int i = 0; i < 230; i++)
                {
                    long[] ts1 = (long[])dd1.Rows[i][0];
                    long[] ts2 = (long[])dd2.Rows[i][0];
                    long pw = (long)dp.Rows[i][0];
                    byte[] bytes2 = System.BitConverter.GetBytes(unchecked((uint)ts1[0]));
                    if (endian) Array.Reverse(bytes2, 0, 4);
                    outStream.Write(bytes2, 0, 4);
                    bytes2 = System.BitConverter.GetBytes(unchecked((uint)ts2[0]));
                    if (endian) Array.Reverse(bytes2, 0, 4);
                    outStream.Write(bytes2, 0, 4);
                    bytes2 = System.BitConverter.GetBytes(unchecked((uint)pw));
                    if (endian) Array.Reverse(bytes2, 0, 4);
                    outStream.Write(bytes2, 0, 4);
                    for (int j = 1; j < 10; j++)
                    {
                        bytes2 = System.BitConverter.GetBytes(unchecked((uint)ts1[j]));
                        if (endian) Array.Reverse(bytes2, 0, 4);
                        outStream.Write(bytes2, 0, 4);
                        bytes2 = System.BitConverter.GetBytes(unchecked((uint)ts2[j]));
                        if (endian) Array.Reverse(bytes2, 0, 4);
                        outStream.Write(bytes2, 0, 4);
                    }
                }

                //write acp
                for (int i = 0; i < 230; i++)
                {
                    long acp1 = (long)dta1.Rows[i][0];
                    long acp2 = (long)dta2.Rows[i][0];
                    byte[] bytes2 = System.BitConverter.GetBytes(unchecked((uint)acp1));
                    if (endian) Array.Reverse(bytes2, 0, 4);
                    outStream.Write(bytes2, 0, 4);
                    bytes2 = System.BitConverter.GetBytes(unchecked((uint)acp2));
                    if (endian) Array.Reverse(bytes2, 0, 4);
                    outStream.Write(bytes2, 0, 4);
                }

                //write unused
                byte[] zr = new byte[820];
                outStream.Write(zr, 0, 820);

                //write label
                zr = new byte[460];
                outStream.Write(zr, 0, 460);

                return String.Empty;
            }
            catch (Exception ex)
            {
                 return ex.ToString();
            }
        }
        //--------------------------------------------------------------------------
        public string ExportSFile(int id, HttpContext context)
        {
            try
            {
                bool endian = BitConverter.IsLittleEndian;
                byte[] b = new byte[4];
                conn = new NpgsqlConnection(
                    String.Format("Server={0};Port={1};User Id={2};Password={3};Database={4};",
                       ConfigurationManager.AppSettings["host"],
                       ConfigurationManager.AppSettings["port"],
                       ConfigurationManager.AppSettings["user"],
                       ConfigurationManager.AppSettings["ps"],
                       ConfigurationManager.AppSettings["db"]));

                conn.Open();
                //--header---
                commandh = new NpgsqlCommand(command_h, conn);
                commandh.Parameters.Add(new NpgsqlParameter("p_type", NpgsqlDbType.Integer));
                commandh.Parameters.Add(new NpgsqlParameter("p_id", NpgsqlDbType.Bigint));
                commandh.Parameters["p_type"].Value = 1; //s тип
                commandh.Parameters["p_id"].Value = id;
                //--power---
                command_s_power = new NpgsqlCommand(sql_s_power, conn);
                command_s_power.Parameters.Add(new NpgsqlParameter("p_hid ", NpgsqlDbType.Bigint));
                command_s_power.Parameters["p_hid"].Value = id;
                //--adc---
                command_s_adc = new NpgsqlCommand(sql_s_adc, conn);
                command_s_adc.Parameters.Add(new NpgsqlParameter("p_hid ", NpgsqlDbType.Bigint));
                command_s_adc.Parameters["p_hid"].Value = id;
                //--akf---
                command_s_akf = new NpgsqlCommand(sql_s_akf, conn);
                command_s_akf.Parameters.Add(new NpgsqlParameter("p_hid ", NpgsqlDbType.Bigint));
                command_s_akf.Parameters["p_hid"].Value = id;

                try
                {
                    NpgsqlDataAdapter das = new NpgsqlDataAdapter(commandh);
                    NpgsqlDataAdapter da_s = new NpgsqlDataAdapter(command_s_power);
                    NpgsqlDataAdapter da_adc = new NpgsqlDataAdapter(command_s_adc);
                    NpgsqlDataAdapter da_akf = new NpgsqlDataAdapter(command_s_akf);
                    das.Fill(myDS, "headers");
                    da_s.Fill(myDS, "powers");
                    da_adc.Fill(myDS, "adc");
                    da_akf.Fill(myDS, "akf");
                    dts = myDS.Tables["headers"];
                    dps = myDS.Tables["powers"];
                    dtas = myDS.Tables["adc"];
                    dtakf = myDS.Tables["akf"];
                    foreach (DataRow row in dtakf.Rows)
                    {
                        long[] ts = (long[])row[0];
                        //foreach (long item in ts)
                        //{
                        //    // MessageBox.Show(item.ToString());
                        //}
                    }
                }
                catch (NpgsqlException nex)
                {
                    return nex.Message;
                }
                finally
                {
                    conn.Close();
                    conn.Dispose();
                    conn = null;
                }

                mDateTime = (DateTime)dts.Rows[0]["measure_date"];
                head[0] = (ushort)mDateTime.Day;
                head[1] = (ushort)mDateTime.Month;
                head[2] = (ushort)mDateTime.Year;
                head[3] = (ushort)mDateTime.Hour;
                head[4] = (ushort)mDateTime.Minute;
                head[5] = (ushort)mDateTime.Second;
                head[6] = ushort.Parse(dts.Rows[0]["seans"].ToString());
                head[7] = ushort.Parse(dts.Rows[0]["nr1"].ToString());
                head[8] = ushort.Parse(dts.Rows[0]["nr2"].ToString());

                String.Format("{0:00000}", 15);

                string attachment = String.Format("attachment; filename=S{0:00}{1:00}{2}.{3:000}", head[0], head[1], head[2].ToString().Substring(head[2].ToString().Length - 2, 2), head[6]);

                context.Response.ClearHeaders();
                context.Response.AddHeader("content-disposition", attachment);

                context.Response.Buffer = false;
                context.Response.ContentType = "application/octet-stream";

                Stream outStream = context.Response.OutputStream;

                MemoryStream mstream = new MemoryStream();
                // write header
                foreach (ushort i in head)
                {
                    byte[] bytes2 = System.BitConverter.GetBytes(i);
                    if (endian) Array.Reverse(bytes2, 0, 2);
                    mstream.Write(bytes2, 0, 2);
                }
                // write power(680) dword 
                for (int i = 0; i < 680; i++)
                {
                    long pws = (long)dps.Rows[i][0];
                    byte[] bytes2 = System.BitConverter.GetBytes(unchecked((uint)pws));
                    if (endian) Array.Reverse(bytes2, 0, 4);
                    mstream.Write(bytes2, 0, 4);
                }
                //write akf(170,18) dword
                for (int i = 0; i < 170; i++)
                {
                    long[] ts1 = (long[])dtakf.Rows[i][0];
                    for (int j = 0; j < 18; j++)
                    {
                        byte[] bytes2 = System.BitConverter.GetBytes(unchecked((uint)ts1[j]));
                        if (endian) Array.Reverse(bytes2, 0, 4);
                        mstream.Write(bytes2, 0, 4);
                    }

                }
                //write adc(680) dword
                for (int i = 0; i < 680; i++)
                {
                    long adc = (long)dtas.Rows[i][0];
                    byte[] bytes2 = System.BitConverter.GetBytes(unchecked((uint)adc));
                    if (endian) Array.Reverse(bytes2, 0, 4);
                    mstream.Write(bytes2, 0, 4);
                }
                //write 300 byte free
                byte[] zrs = new byte[300];
                mstream.Write(zrs, 0, 300);
                //write label(180) dword
                zrs = new byte[360];
                mstream.Write(zrs, 0, 360);
                context.Response.AppendHeader("content-length", mstream.Length.ToString());
                mstream.Position = 0;
                mstream.CopyTo(outStream);

                return String.Empty;
            }
            catch (Exception ex)
            {
                return ex.ToString();
            }
        }
    }
}
